<?php

class Simplium_Db_Adapter_Pdo_Abstract extends Simplium_Db_Adapter_Abstract{
	/**
	 * @var Pdo
	 */
	protected $_connection = null;
	protected $_pdotype = 'mysql';
	
	protected function _dsn(){
		$dsn = $this->_options;
		
		unset($dsn['username'], $dsn['password'], $dsn['charset']);
		
		foreach($dsn as $key => $value){
			$dsn[$key] = $key . '=' . $value;
		}
		
		return $this->_pdotype . ':' . implode(';', $dsn);
	}
	
	/**
	 * @param array $array
	 */
	public function connect(array $array = array()){
		if($this->_connection){
			return;
		}
		
		$dsn = $this->_dsn();
		
		if(isset($this->_options['presistent']) && $this->_options['presistent'] == true){
			$this->_options['driver_options'][PDO::ATTR_PERSISTENT] = true;
		}
		
		try{
			$this->_connection = new PDO(
				$dsn, $this->_options['username'], 
				$this->_options['password'], 
				$this->_options['driver_options']
			);
			
			// always use exceptions.
			$this->_connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
		}catch(PDOException $e){
			throw new PDOException($e->getMessage(), $e->getCode());
		}
	}
	
	/**
	 * @param string $tblname
	 * @param array $data
	 */
	public function insert($tblname, array $data){
		$cols = array();
		$vals = array();
		foreach ($data as $k => $v) {
			$cols[] = $this->quoteIdentifier($k, true);
			$vals[] = '?';
		}

		$sql = "INSERT INTO "
			 . $this->quoteIdentifier($tblname, true) 
			 . ' (' . implode(', ', $cols) . ') ' 
			 . 'VALUES (' . implode(', ', $vals) . ')';

		$stmt 	= $this->query($sql, array_values($data));
		$result = $stmt->rowCount();

		return $result;
	}
	
	/**
	 * @param string $tblname
	 * @param array $data
	 * @param mixed $where
	 */
	public function update($tblname, array $data, $where = ''){
		$set = array();
		
		foreach($data as $k => $v){
			$set[] = $this->quoteIdentifier($k, true) . '= ?';
		}
		
		$where = $this->_whereExpr($where);
		
		$sql = "UPDATE " 
			 . $this->quoteIdentifier($tblname, true) 
			 . ' SET ' . implode(', ', $set) 
			 . (($where) ? " WHERE $where" : '');
			 
		$stmt 	= $this->query($sql, array_values($data));
		$result = $stmt->rowCount();
		
		return $result;
	}
	
	/**
	 * @param string $tblname
	 * @param mixed $where
	 */
	public function delete($tblname, $where = ''){
		$where = $this->_whereExpr($where);

		$sql = "DELETE FROM " 
			 . $this->quoteIdentifier($tblname, true)
			 . (($where) ? " WHERE $where" : '');
			 
		$stmt 	= $this->query($sql);
		$result = $stmt->rowCount();
		
		return $result;
	}
	
	/**
	 * 
	 * @param string $stmt
	 * @param array $bind
	 * @return PDOStatement
	 */
	public function query($stmt, $bind = array()){
		$stmt = $this->_connection->prepare($stmt);
		$stmt->execute($bind);
		
		return $stmt;
	}
	
	/**
	 * Quote a raw string.
	 *
	 * @param string $value
	 * @return string Quoted string
	 */
	protected function _quote($value){
		if (is_int($value) || is_float($value)) {
			return $value;
		}
        
		return $this->_connection->quote($value);
	}
}